package mobi.hami.huapin.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import mobi.hami.huapin.config.AppConfig;
import mobi.hami.huapin.constants.BaseEnums;
import mobi.hami.huapin.core.stock.StockUtil;
import mobi.hami.huapin.dao.*;
import mobi.hami.huapin.dto.*;
import mobi.hami.huapin.exception.BaseException;
import mobi.hami.huapin.exception.GlobalExceptionConfig;
import mobi.hami.huapin.model.*;
import mobi.hami.huapin.model.base.PageQO;
import mobi.hami.huapin.model.base.PageVO;
import mobi.hami.huapin.service.ProductForEndService;
import mobi.hami.huapin.service.ProductService;
import mobi.hami.huapin.service.SubjectService;
import mobi.hami.huapin.util.CommonPage;
import mobi.hami.huapin.util.SearchListUtil;
import mobi.hami.huapin.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.*;

/**
 * 类说明
 *
 * @author 阿飞 jijunjian@hami.mobi
 * @date 2018/8/16 16:47
 */
@Service
public class ProductForeEndServiceImpl implements ProductForEndService {

    private static final Logger logger = LoggerFactory.getLogger(ProductForeEndServiceImpl.class);

    protected final static ExecutorService THREAD_POOL = new ThreadPoolExecutor(4,4,5L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1600));

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private  ProductskuMapper skuMapper;

    @Autowired
    SubjectService subjectService;

    @Autowired
    AppConfig appConfig;

    @Autowired
    SkuPictureMappingMapper skuPictureMappingMapper;
    @Autowired
    OpinionLeaderMapper opinionLeaderMapper;
    @Autowired
    ProductShowAttributeMapper showAttributeMapper;
    @Autowired
    SkuAttributeMapper skuAttributeMapper;
    @Autowired
    SkuAttributevalueMapper skuAttributevalueMapper;
    @Autowired
    SkuProductattributeMappingMapper skuProductattributeMappingMapper;
    @Autowired
    private StockUtil stockUtil;


    /**
     * 查询条数
     *
     * @param where
     * @return
     */
    @Override
    public int getCount(String where) {

        String  sql  =   "SELECT COUNT(1) from  product \n" +
                "    WHERE 1=1 "+ where;

        int rs  = jdbcTemplate.queryForObject(sql,null,Integer.class);

        return rs;
    }


    @Override
    public PageVO<ProductForUserDTO>  getListForUser(Map<String,Object> reqMap) {

        PageQO pageQO = SearchListUtil.resolveSearchData(reqMap);

        //1 获取主题
        Long subject_id = 0L;
        if (reqMap.containsKey("subject_id")) {
            subject_id = Long.parseLong(reqMap.get("subject_id").toString());
        }
        if (subject_id <= 0) //根据周几找一个主题
        {
            Subject todaysubject = subjectService.getTodaySubject(new Date());
            if (null == todaysubject)
            {
                throw  new BaseException(BaseEnums.NOT_FOUND.code(),BaseEnums.NOT_FOUND.desc());
            }
            else
            {
                subject_id = todaysubject.getId();
            }
        }

        // 获取 商品

        return  getListForUserBy(subject_id);

    }



    /**
     * 根据 spuid　查询相关信息
     *
     * @param spu_id
     * @return
     */
    //@Cacheable(value = "getSpuData",keyGenerator = "firstParamKeyGenerator")
    //@Cacheable(value = "getSpuData",key = "'getSpuData'+#spu_id")
    @Override
    public SPUDTO getSpuData(long spu_id) {

        SPUDTO spudto = new SPUDTO();
        List<SKUForUserDTO> products = skuMapper.getProductSkuListBySpuID(spu_id);
        products.forEach(a ->
        {
            a.setProductattributeMappings(skuProductattributeMappingMapper.getMappingForSku(a.getId()));
        });

        spudto.setProductskuList(products);



        List<SkuAttribute> skuAttributes = skuAttributeMapper.getListForUser(spu_id);
        spudto.setSkuAttributeList(skuAttributes);

        List<SkuAttributevalue> skuAttributevalues = skuAttributevalueMapper.getListForUser(spu_id);
        spudto.setSkuAttributevalueList(skuAttributevalues);



        return spudto;
    }


    /**
     * 根据 主题 编号 获取用户端的端口列表
     * @param subject_id
     * @return
     */
    //@Cacheable(value = "getListForUserBy",key = "'getListForUserBy'+#subject_id")
    public PageVO<ProductForUserDTO> getListForUserBy(Long subject_id) {

        // 获取 商品
        List<SpuSubjectMapping> spuIDs = subjectService.getSpuBySubjectID(subject_id);
        StringBuilder stringBuilder = new StringBuilder();
        spuIDs.forEach(a->{
            stringBuilder.append(a.getSpu_id()+",");
        });

        String ids = StringUtil.deleteLastLetter(stringBuilder.toString());

        if (ids.length() == 0)
        {
            throw new BaseException(BaseEnums.NOT_FOUND.code(),BaseEnums.NOT_FOUND.desc());
        }

        //1， 找 sku
        List<ProductForUserDTO> products = productMapper.getListForUser(ids);

        //使用多线程处理；

        //2， 找 图片
        List<SkuPictureMapping>  pictureMappingLis = skuPictureMappingMapper.getListForUser(ids);

        //3, 找 意见 暂时没有意见领袖了
        //List<OpinionLeader>  opinionLeaders = opinionLeaderMapper.getListForUser(ids);

        //4, 显示属性
        List<ProductShowAttribute>  productShowAttributes = showAttributeMapper.getListForUser(ids);

        //5 查库存  通过 http接口查库存
        List<SkuStockDTO> stockDTOS =  stockUtil.queryBat(ids,"");

        // 设置数据
        products.forEach(product->{

            //设置图片
            List<SkuPictureMapping> pictures = new ArrayList<>();

            pictureMappingLis.forEach(pic ->{
                if (product.getId() == (long)(pic.getSpuid()))
                {
                     if (pic.getMastertag() == 1)
                     {
                         product.setMaster_pic(pic.getPictuire());
                     }
                    if (pic.getMastertag() ==2)
                    {
                        product.setSamll_pic(pic.getPictuire());
                    }
                    if (pic.getMastertag() ==3)
                    {
                        pictures.add(pic);
                    }
                }


            });

            if(  product.getMaster_pic() != null &&  product.getMaster_pic().length() > 0 )
            {
                SkuPictureMapping masterpic = new SkuPictureMapping();
                masterpic.setPictuire(product.getMaster_pic());
                pictures.add(0,masterpic);
            }

            product.setDetail_pics(pictures);

            /*
            List<OpinionLeader>  myopinions = new ArrayList<>();
            opinionLeaders.forEach(opinionLeader -> {

                if ((long)opinionLeader.getSpu_id() == product.getId())
                {
                    myopinions.add(opinionLeader);
                }
            });
            product.setOpinionLeaderList(myopinions);
            */

            List<ProductShowAttribute>  myproductShowAttributes = new ArrayList<>();
            productShowAttributes.forEach(productShowAttribute -> {
                if ((long)productShowAttribute.getSpu_id() == product.getId())
                {
                    myproductShowAttributes.add(productShowAttribute);
                }
            });
            product.setProductShowAttributes(myproductShowAttributes);

            product.setSubject_id(subject_id);
        });

        // todo 找库存


        PageVO vo = PageVO.build(products);
        vo.setTotalCount((long)products.size());

        //logger.info("条数",pages.getTotal());

        return vo;

    }


    /**
     * 分页获取 test  多线程
     *
     * @param reqMap
     * @return
     */
    @Override
    public PageVO<ProductForUserDTO> getListForUserByCountDownPool(Map<String, Object> reqMap) {

        PageQO pageQO = SearchListUtil.resolveSearchData(reqMap);

        //1 获取主题
        Long subject_id = 0L;
        if (reqMap.containsKey("subject_id")) {
            subject_id = Long.parseLong(reqMap.get("subject_id").toString());
        }
        if (subject_id <= 0) //根据周几找一个主题
        {
            Subject todaysubject = subjectService.getTodaySubject(new Date());
            if (null == todaysubject)
            {
                throw  new BaseException(BaseEnums.NOT_FOUND.code(),BaseEnums.NOT_FOUND.desc());
            }
            else
            {
                subject_id = todaysubject.getId();
            }
        }

        // 获取 商品

        return  getListForUserByCountDownPool(subject_id);
    }

    /**
     * 根据 主题 编号 获取用户端的端口列表 (多线程实现)
     * @param subject_id
     * @return
     */
    //@Cacheable(value = "getListForUserBy",key = "'getListForUserBy'+#subject_id")
    public PageVO<ProductForUserDTO> getListForUserByCountDownPool(Long subject_id) {

        // 获取 商品
        List<SpuSubjectMapping> spuIDs = subjectService.getSpuBySubjectID(subject_id);
        StringBuilder stringBuilder = new StringBuilder();
        spuIDs.forEach(a->{
            stringBuilder.append(a.getSpu_id()+",");
        });

        String ids = StringUtil.deleteLastLetter(stringBuilder.toString());

        if (ids.length() == 0)
        {
            throw new BaseException(BaseEnums.NOT_FOUND.code(),BaseEnums.NOT_FOUND.desc());
        }

        ProductMergeDTO productMergeDTO = new ProductMergeDTO();

        CountDownLatch countDownLatch = new CountDownLatch(3);

        //1， 找 sku
        //List<ProductForUserDTO> products = productMapper.getListForUser(ids);


        productMergeDTO.setSkus( productMapper.getListForUser(ids));


        //2， 找 图片
        //List<SkuPictureMapping>  pictureMappingLis = skuPictureMappingMapper.getListForUser(ids);

        THREAD_POOL.execute(()->{
            productMergeDTO.setPics(skuPictureMappingMapper.getListForUser(ids));
            countDownLatch.countDown();
        });

        //3, 找 意见 暂时没有意见领袖了
        //List<OpinionLeader>  opinionLeaders = opinionLeaderMapper.getListForUser(ids);

        //4, 显示属性
        //List<ProductShowAttribute>  productShowAttributes = showAttributeMapper.getListForUser(ids);

        THREAD_POOL.execute(()->{
            productMergeDTO.setShowAttributes(showAttributeMapper.getListForUser(ids));
            countDownLatch.countDown();
        });


        //5 查库存  通过 http接口查库存
        THREAD_POOL.execute(()->{

            final StringBuilder skuids = new StringBuilder();
            productMergeDTO.getSkus().forEach(a->
            {
                skuids.append(a.getSkuid()+",");
            });
            if (skuids.toString().length() > 0)
            {
                String sku_ids = StringUtil.deleteLastLetter(skuids.toString());
                productMergeDTO.setSkuStockDTOS(stockUtil.queryBat(sku_ids,""));
            }
            else
            {
                productMergeDTO.setSkuStockDTOS(new ArrayList<>());
            }
            countDownLatch.countDown();

        });


        try {
            countDownLatch.await(1,TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 设置数据
        productMergeDTO.getSkus().forEach(product->{

            //设置图片
            List<SkuPictureMapping> pictures = new ArrayList<>();

            productMergeDTO.getPics().forEach(pic ->{
                if (product.getId() == (long)(pic.getSpuid()))
                {
                    if (pic.getMastertag() == 1)
                    {
                        product.setMaster_pic(pic.getPictuire());
                    }
                    if (pic.getMastertag() ==2)
                    {
                        product.setSamll_pic(pic.getPictuire());
                    }
                    if (pic.getMastertag() ==3)
                    {
                        pictures.add(pic);
                    }
                }
            });

            if(  product.getMaster_pic() != null &&  product.getMaster_pic().length() > 0 )
            {
                SkuPictureMapping masterpic = new SkuPictureMapping();
                masterpic.setPictuire(product.getMaster_pic());
                pictures.add(0,masterpic);
            }

            product.setDetail_pics(pictures);

            /*
            List<OpinionLeader>  myopinions = new ArrayList<>();
            opinionLeaders.forEach(opinionLeader -> {

                if ((long)opinionLeader.getSpu_id() == product.getId())
                {
                    myopinions.add(opinionLeader);
                }
            });
            product.setOpinionLeaderList(myopinions);
            */

            List<ProductShowAttribute>  myproductShowAttributes = new ArrayList<>();
            productMergeDTO.getShowAttributes().forEach(productShowAttribute -> {
                if ((long)productShowAttribute.getSpu_id() == product.getId())
                {
                    myproductShowAttributes.add(productShowAttribute);
                }
            });
            product.setProductShowAttributes(myproductShowAttributes);
            product.setStock(0);
            productMergeDTO.getSkuStockDTOS().forEach(a ->{
                if (product.getSkuid() == (long)(a.getSku_id()))
                {
                    product.setStock(a.getNum()*99);
                    return;
                }
            });

            product.setSubject_id(subject_id);
        });

        // todo 找库存


        PageVO vo = PageVO.build(productMergeDTO.getSkus());
        vo.setTotalCount((long)productMergeDTO.getSkus().size());

        //logger.info("条数",pages.getTotal());

        return vo;

    }

    /**
     * 查询条数
     *
     * @param reqMap
     * @return
     */
    @Override
    public int getCount(Map<String, Object> reqMap) {

        ProductExample example = new ProductExample();
        ProductExample.Criteria criteria = example.createCriteria();
        criteria.andSubject_idEqualTo(9);

        int count = productMapper.selectCountByExample(example);

        return count;
    }



    /**
     * mapper 分页面
     * @param pageindex
     * @param pagesize
     * @param order
     * @return
     */
    public PageVO<Product> pageTest(int pageindex, int pagesize, String order, Product smarBoxCompanyDTO) {

        PageHelper.startPage(pageindex, pagesize);
        List<Product> list = productMapper.getPageTest(smarBoxCompanyDTO);

        PageInfo<Product> pages=new PageInfo<>(list);

        PageVO vo = PageVO.build(list);
        vo.setPages(pageindex);
        vo.setTotalCount((long)( pages.getTotal()));
        vo.setPages(pagesize);

        logger.info("条数" + pages.getTotal());

        return vo;
    }


}
